
-- module Distribution.Graphs where
module Main where

import Distribution.Common
-- import Graphics.Gnuplot.Simple
import Fetcher
import Distribution.FractalDist
import Distribution.Time
import Distribution.PowerLaw
import Data.Time
import Data.Time.Calendar.WeekDate
import Database.HDBC
import Control.Monad
import Kalman

recalcK [x] = calculateK [x]
recalcK []   = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

getKforDay :: IConnection c => c -> TableBar -> LocalTime -> IO (LocalTime, Double, Double, Double)
getKforDay c bar day = do
                let td = addDay 1 day
                dist <- fetchLowChanges c bar 1 day td
                let (calcC, calcK, _, _, _, _) = calculateK dist
                return (day, -calcK, calcC, (log (-calcK)) - 2*calcC)

printInfo4 :: (Show a1, Show a3, Show a2, Show a) => (a, a1, a2, a3) -> IO ()
printInfo4 (day, k, c, d) = do
        putStrLn $ (show day) ++","++(show k)++","++(show c)++","++(show d)
        
printInfo3 ::  (Show a1, Show a2, Show a) => (a, a1, a2) -> IO ()
printInfo3 (day, k, c) = do
        putStrLn $ (show day) ++","++(show k)++","++(show c)

dayProcessing ::  IConnection c => c -> IO ()
dayProcessing c = do
        let bar = MinuteBar
        let fd  = LocalTime (fromGregorian 2010 01 01) (TimeOfDay 0 0 0)
        let days = [0..90]
        let fds = map (\x -> addDay x fd) days
        let workdays = filter isWorkDay fds
        dCalcs <- mapM (getKforDay c bar) workdays
        forM_ dCalcs printInfo4

getKforRange :: (IConnection c, Show t) =>c -> TableBar -> (t, t) -> IO (t, Double, Double)
getKforRange conn bar (fd, td) = do
        dist <- fetchLowChanges conn bar 1 fd td 
        let (c, k, _, _, _, _) = calculateK dist
        return (fd, k, c)

getKforBars :: IConnection conn => conn->[TableBar]->(LocalTime, LocalTime)->IO (LocalTime, [Double])
getKforBars conn bars (fd, td) = do
        dCalcs <- mapM (\x -> getKforRange conn x (fd, td)) bars
        return $ (fd, map (\(_, k, _) -> k) dCalcs)

getPowerForRange conn bar (fd, td) = do
        dist <- fetchLowChanges conn bar 1 fd td
        return $ estimatePower dist

getPowerForBars conn bars (fd, td) = do
        dCalcs <- mapM (\x -> getPowerForRange conn x (fd, td)) bars
        return (fd, dCalcs)

printResult (t, xs) = do
        putStrLn $ toString (t, xs)

toString (t, xs) = (show t)++(printArray xs)
        where   printArray []           = ""
                printArray (s:ss)       = ","++(show s)++(printArray ss)

scaledKeys (t, [m, h, f]) = (t, [m/h, m/f, h/f])
antiscaleKeys (t, [m, h, f]) = (t, [h/m, f/m, f/h])

filterKeys x = filter (\(t0, k) -> all (\m -> (m>0) && (m<100)) k) x

weekProcessing c year = do
        let weeks = [1..52]
        let bars  = [MinuteBar, HourBar, FourBar]
        let days  = map (getWorkWeek year) weeks
        dCalcs <- mapM (getKforBars c bars) days
        let scaledK = filterKeys $ map scaledKeys dCalcs
        print $ findKalmanEstimate scaledK
        forM_ scaledK printResult

weekPower c year = do
        let weeks       = [1..51]
        let bars        = [MinuteBar, HourBar, FourBar]
        let days        = map (getWorkWeek year) weeks
        dCalcs <- mapM (getPowerForBars c bars) days
        let scaledK = map antiscaleKeys dCalcs
        forM_ scaledK printResult

main :: IO ()
main = do
        c <- defaultConnection
        let years = [2010..2010]
        forM_ years (weekPower c)
        disconnect c
